// class 形态的 Promise
class Promise{

    //构造方法
    constructor(executor){
        // 声明状态属性
        this.PromiseState = 'pending';
        // 声明结果值属性
        this.PromiseResult = undefined;
        // 声明属性
        this.callbacks = [];

        //声明 success 函数
        let success = (value) => {
            //判断
            if(this.PromiseState !== 'pending') return;
            //作用:                       实例对象属性
            //1. 修改实例对象『状态』为成功  PromiseState
            this.PromiseState = 'fulfilled';
            //2. 设置成功的『结果值』       PromiseResult
            this.PromiseResult = value;
            //执行待执行的回调
            if(this.callbacks.length > 0){
                setTimeout(() => {
                    this.callbacks.forEach(cbObj => {
                        //执行成功的回调
                        cbObj.ok();
                    })
                })
            }
        }

        //声明 error 函数
        let error = (reason) => {
            if(this.PromiseState !== 'pending') return;

            this.PromiseState = 'rejected';
            this.PromiseResult = reason;
            //执行失败的回调
            if(this.callbacks.length > 0){
                setTimeout(() => {
                    this.callbacks.forEach(cbObj => {
                        //执行成功的回调
                        cbObj.ng();
                    })
                })
            }
        }
        try{
            //执行 executor
            executor(success, error);
        }catch(e){
            //如果抛出错误, 修改 promise 状态为失败
            error(e);   
        }
    }

    //添加 then 方法
    then(onFulfilled, onRejected){
        //为 onRejected 设置默认值
        if(typeof onRejected !== 'function'){
            onRejected = reason => {
                throw reason;
            }
        }

        if(typeof onFulfilled !== 'function'){
            onFulfilled = value => value;
        }

        //执行对应的回调函数
        return new Promise((resolve, reject) => {
            //声明一个函数 『handle 处理的意思』
            let handle = (type) => {
                try{
                    //获取回调函数的返回值
                    let res = type(this.PromiseResult);
                    //判断
                    if(res instanceof Promise){
                        //2. 返回 promise 类型的值
                        res.then(v => {
                            resolve(v);
                        }, r => {
                            reject(r);
                        })
                    }else{
                        //1. 返回非 promise 类型的值
                        resolve(res);
                    }
                }catch(e){
                    //3. 抛出错误/异常
                    reject(e);
                }
            }
            //判断 promise 状态是否为成功
            if(this.PromiseState === 'fulfilled'){
                setTimeout(() => {
                    handle(onFulfilled);
                })
            }
            //失败的情况
            if(this.PromiseState === 'rejected'){
                setTimeout(() => {
                    handle(onRejected);
                })
            }
            //判断
            if(this.PromiseState === 'pending'){
                //将回调函数保存起来
                this.callbacks.push({
                    //状态改为成功的时候, 执行
                    ok: function(){
                        //执行成功的回调
                        handle(onFulfilled);
                    },
                    //状态改为失败的时候, 执行
                    ng: function(){
                        handle(onRejected);
                    }
                })
            }
        })
    }

    //添加 catch 方法
    catch(onRejected){
        return this.then(undefined, onRejected);
    }

    //resolve  static 声明静态成员
    static resolve(value){
        return new Promise((resolve, reject) => {
            //判断
            if(value instanceof Promise){
                //value 是 promise 对象
                value.then(resolve, reject);
            }else{
                //value 不是 promise 对象
                resolve(value);
            }
        });
    }

    //reject
    static reject(reason){
        return new Promise((resolve, reject) => {
            reject(reason);
        });
    }

    //all
    static all(promiseArr){
        //声明一个数组
        let data = [];
        //声明计数器
        let count = 0;
        //返回值 promise 对象
        return new Promise((resolve, reject) => {
            //resolve  reject 
            //遍历
            promiseArr.forEach((item, index) => {
                //调用 then 方法
                item.then(v=>{
                    //当所有的 promise 对象状态都为成功的时候, 才能调用 resolve 函数, 并设置成功的结果值
                    // data.push(v);
                    data[index] = v; // data[2] = 'Yeah'
                    //成功一个自增
                    count++;
                    //判断长度是否已满
                    if(count === promiseArr.length){
                        resolve(data);
                    }
                }, r=>{
                    //如果当前 promise 失败, 则修改 all 返回 promise 状态为失败
                    reject(r);
                })
            })
        });
    }  

    //race
    static race(promiseArr){
        return new Promise((resolve, reject) => {
            //遍历数组
            promiseArr.forEach(item => {
                item.then(v => {
                    resolve(v);
                }, r => {
                    reject(r);
                })
            });
        })
    }

}
